package haiyan.common.email;

import java.util.Properties;

import javax.activation.DataHandler;
import javax.activation.DataSource;
import javax.activation.FileDataSource;
import javax.mail.Address;
import javax.mail.BodyPart;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Multipart;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;

import haiyan.common.DebugUtil;

/**
 * @author zhouxw
 * 
 */
public class EmailSender {

	private Session session;

	private MimeMessage mimeMsg; // MIME mail object

	private Multipart mp; // Multipart

	private Properties props; // system property

	// private boolean needAuth = false;

	private String username;

	private String password;

	private String mailSubject;

	private String fileName;

	private String htmlPath;

	private String mailBody;
	
	private String charset;

	private String text;

	private String copyto;

	private String from;

	private String to;

	/**
	 * @param smtp
	 */
	public EmailSender(String smtp) {
		setSmtpHost(smtp);
	}

	/**
	 * @param hostName
	 *            String
	 */
	public void setSmtpHost(String hostName) {
		DebugUtil.debug(">smtp.host=" + hostName);
		if (props == null) {
			props = System.getProperties();
		}
		props.put("mail.smtp.host", hostName);
	}

	/**
	 * @param need
	 *            boolean
	 */
	public void setNeedAuth(boolean need) {
		DebugUtil.debug(">smtp.auth=" + need);
		if (props == null) {
			props = System.getProperties();
		}
		if (need) {
			props.put("mail.smtp.auth", "true");
		} else {
			props.put("mail.smtp.auth", "false");
		}
	}

	/**
	 * @param name
	 *            String
	 * @param pass
	 *            String
	 */
	public void setNamePass(String name, String pass) {
		this.username = name;
		this.password = pass;
	}

	/**
	 * @param mailSubject
	 *            String
	 * @return boolean
	 */
	public void setSubject(String mailSubject) {
		this.mailSubject = mailSubject;
	}

	/**
	 * @param filename
	 * @return boolean
	 */
	public void addFileAffix(String fileName) {
		this.fileName = fileName;
	}

	/**
	 * @param from
	 * @return boolean
	 */
	public void setFrom(String from) {
		this.from = from;
	}

	/**
	 * @param to
	 * @return boolean
	 */
	public void setTo(String to) {
		this.to = to;
	}

	/**
	 * @param copyto
	 * @return boolean
	 */
	public void setCopyTo(String copyto) {
		this.copyto = copyto;
	}

	/**
	 * @param text
	 * @return boolean
	 */
	public void setText(String text) {
		this.text = text;
	}

	/**
	 * @param mailBody
	 * @param charsets
	 * @return boolean
	 */
	public void setBody(String mailBody, String... charsets) {
		this.mailBody = mailBody;
		this.charset = "UTF-8";
		if (charsets.length > 0)
			this.charset = charsets[0];
	}

	/**
	 * @param htmlPath
	 * @return boolean
	 */
	public void setHtml(String htmlPath) {
		this.htmlPath = htmlPath;
	}

	/**
	 * @return boolean
	 * @throws MessagingException 
	 */
	public boolean createMimeMessage() throws MessagingException {
		try {
			DebugUtil.debug(">session begin-----");
			session = Session.getInstance(props, null);
		} catch (Throwable e) {
			DebugUtil.error("Session.getInstance failed:", e);
			return false;
		}
		try {
			DebugUtil.debug(">MimeMessage begin-----");
			mimeMsg = new MimeMessage(session);
			mp = new MimeMultipart();
			mimeMsg.setContent(mp);
		} catch (Throwable e) {
			DebugUtil.error("MimeMessage failed:" + e);
			return false;
		}
		try {
			DebugUtil.debug(">set Mail From " + from);
			mimeMsg.setFrom(new InternetAddress(from));
		} catch (Throwable e) {
			DebugUtil.error("Set From Fialed.", e);
			return false;
		}
		try {
			DebugUtil.debug(">set Mail To " + to);
			mimeMsg.setRecipients(Message.RecipientType.TO,
					InternetAddress.parse(to));
		} catch (Throwable e) {
			DebugUtil.error("Set To Fialed.", e);
			return false;
		}
		if (copyto != null && !copyto.equals("")) {
			try {
				DebugUtil.debug(">set Mail CopyTo " + copyto);
				int i = 0;
				String copy[] = copyto.split(";");
				for (i = 0; i < copy.length; i++) {
					mimeMsg.setRecipients(Message.RecipientType.CC,
							(Address[]) InternetAddress.parse(copy[i]));
				}
			} catch (Throwable e) {
				DebugUtil.error("Set CC Fialed.", e);
				return false;
			}
		}
		if (mailSubject != null && !mailSubject.equals("")) {
			try {
				DebugUtil.debug(">set title begin-----");
				mimeMsg.setSubject(mailSubject);
			} catch (Throwable e) {
				DebugUtil.error("set title failed.", e);
				return false;
			}
		}
		if (text != null && !text.equals("")) {
			try {
				DebugUtil.debug(">set Mail text " + text);
				BodyPart bp = new MimeBodyPart();
				bp.setText(text);
				mp.addBodyPart(bp);
			} catch (Throwable e) {
				DebugUtil.error("Set text Fialed.", e);
				return false;
			}
		}
		if (fileName != null && !fileName.equals("")) {
			try {
				DebugUtil.debug(">fileName:" + fileName);
				String file[] = fileName.split(";");
				// System.err.println("========" + file.length);
				for (int i = 0; i < file.length; i++) {
					BodyPart bp = new MimeBodyPart();
					FileDataSource fileds = new FileDataSource(file[i]);
					bp.setDataHandler(new DataHandler(fileds));
					bp.setFileName(fileds.getName());
					mp.addBodyPart(bp);
				}
			} catch (Throwable e) {
				DebugUtil.error(">fileName:" + fileName + "--failed:" + e);
				return false;
			}
		}
		if (mailBody != null && !"".equals(mailBody)) {
			try {
				BodyPart bp = new MimeBodyPart();
				bp.setContent(
						"<meta http-equiv=Content-Type content=text/html; charset="
								+ charset + ">" + mailBody,
						"text/html;charset=" + charset);
				mp.addBodyPart(bp);
			} catch (Throwable e) {
				DebugUtil.error("Set body Fialed.", e);
				return false;
			}
		}
		if (htmlPath != null && !htmlPath.equals("")) {
			try {
				BodyPart mbp = new MimeBodyPart();
				DataSource ds = new FileDataSource(htmlPath);
				mbp.setDataHandler(new DataHandler(ds));
				mbp.setHeader("Content-ID", "meme");
				mp.addBodyPart(mbp);
			} catch (Throwable e) {
				DebugUtil.error("Set html Failed.", e);
				return false;
			}
		}
		mimeMsg.saveChanges();
		return true;
	}

	/**
	 * @return boolean
	 */
	public boolean sendout() {
		Transport transport = null;
		try {
			if (!createMimeMessage())
				return false;
			DebugUtil.debug(">Sending mail...");
			// Session mailSession = Session.getInstance(props, null);
			transport = session.getTransport("smtp");
			transport.connect((String) props.get("mail.smtp.host"), username,
					password);
			Address[] toAdrs = mimeMsg.getRecipients(Message.RecipientType.TO);
			transport.sendMessage(mimeMsg, toAdrs);
			Address[] ccAdrs = mimeMsg.getRecipients(Message.RecipientType.CC);
			if (ccAdrs != null)
				transport.sendMessage(mimeMsg, ccAdrs);
			DebugUtil.debug(">Mail Send Success.");
		} catch (Throwable e) {
			DebugUtil.error("Mail Send Failed.", e);
			return false;
		} finally {
			if (transport != null)
				try {
					transport.close();
				} catch (Throwable e) {
					DebugUtil.error(e);
				}
		}
		return true;
	}

}
